/* R. J. Cano, Jul 22 2014

  Catalan's books: An enumerative combinatorics exercise.

  Some relevant counters associated to books made with
  all the possible words written on a fixed number of
  letters in a given alphabet, such that these letters
  are read in lexicographic non-decreasing order from
  left to right.
 */

/* Saves a book as a plain text file */

book=(wordSize,alphabetSize,filename)->\
 forvec(y=vector(wordSize,k,[0,alphabetSize-1]),write(filename,y),1);

/* Number of times that any letter is repeated in a book,
   if all the words are of the same size */
   
howManyTimesAnyLetterInTheBook=(wordSize,alphabetSize)->\
binomial(alphabetSize-1+wordSize,alphabetSize);

/* Number of words in a book,
   if all the words are of the same size */
   
howManyWordsInTheBook=(wordSize,alphabetSize)->\
binomial(alphabetSize-1+wordSize,alphabetSize-1);

/*
   Connection with the Catalan's triangle
   (Sequence A009766 at OEIS)

   The numbers at the rows in the Catalan's triangle count
   the differences when there are NO less words in a book
   than the number of times that any letter is repeated inside
   such book. The size of the alphabet would be row+1 relative
   to the triangle, and the size of the word would be column-1
   assuming that the columns are labeled from left to right
   starting with 1. If such labels start with zero, the size
   of the words is simply column.
   
   Note: For the zeroth row of the triangle and/or the first
   column in the representation generated below, this
   interpretation doesn't apply, however the mathematical
   behavior here described is hold due the underlying
   conventions and definitions for binomial coefficients.   
 */

/* Return -1 if the answer is "No".
   Otherwise returns the difference */

NoLessWordsThanTimesRepeatedAnyLetter=(wordSize,alphabetSize)->\
 {my(Answer=howManyWordsInTheBook(wordSize,alphabetSize)-\
 howManyTimesAnyLetterInTheBook(wordSize,alphabetSize));\
 if(Answer>=0,Answer,-1)}

/* The Catalan's triangle is printed as follows:
   (By default only the first 10 rows are shown) */
   
CatalanTriangle=(rows=10)-> for(alphabetSize=1,rows,\
 for(wordSize=0,alphabetSize-1,\
 print1(" "\
 NoLessWordsThanTimesRepeatedAnyLetter(wordSize,alphabetSize)));\
 print1("\n")\
);

{print("\nFirst 10 rows of the triangle:\n");CatalanTriangle();}

/* Acknowledgments to:
 *  The On-Line Encyclopedia Of Integer Sequences (OEIS)
 *  and The PARI-GP development team, for their valuable
 *  time, moral support and the formidable work they do.
*/